package com.smasher.doc.operation;

import android.content.ContentResolver;
import android.content.res.Resources;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.RawRes;

import com.smasher.doc.entity.CacheEntity;

import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class OperationReadHelper {


    private static final String TAG = "OperationReadHelper";

    private Callback callback;

    public OperationReadHelper(Callback callback) {
        this.callback = callback;
    }

    /**
     * 方式1
     *
     * @param resources resources
     * @param id        id
     */
    public void readDocFromRaw(
            final Resources resources,
            @RawRes int id
    ) {
        GenerateInputStream stream = new TargetInputStream() {
            @Override
            public InputStream generateRaw(Resources resources, int id) throws IOException {
                return resources.openRawResource(id);
            }
        };

        readDocActualRaw(stream, resources, id);
    }


    /**
     * 方式2
     *
     * @param name name
     */
    public void readDocFromExternal(
            String name,
            File parent
    ) {
        File target = new File(parent, name);
        GenerateInputStream stream = new TargetInputStream() {

            @Override
            public InputStream generateFile(File file) throws FileNotFoundException {
                return new FileInputStream(file);
            }
        };

        readDocActualFile(stream, target);
    }


    /**
     * 方式3
     *
     * @param uri uri
     */
    public void readDocFromUri(
            ContentResolver contentResolver,
            Uri uri
    ) {
        GenerateInputStream stream = new TargetInputStream() {

            @Override
            public InputStream generateUri(ContentResolver contentResolver, Uri uri) throws FileNotFoundException {
                return contentResolver.openInputStream(uri);
            }
        };

        readDocActualUri(stream, contentResolver, uri);
    }

    //=================================================================================================

    private void readDocActualRaw(
            GenerateInputStream stream,
            final Resources resources,
            @RawRes int id
    ) {
        try (InputStream inputStream = stream.generateRaw(resources, id)) {
            readActual(inputStream);
        } catch (Exception e) {
            Log.e(TAG, "readDocFromRaw: ", e);
        }
    }


    private void readDocActualFile(
            GenerateInputStream stream,
            File file
    ) {
        try (InputStream inputStream = stream.generateFile(file)) {
            readActual(inputStream);
        } catch (IOException e) {
            Log.e(TAG, "io exception: ", e);
        } catch (Exception e) {
            Log.e(TAG, "exception: ", e);
        }
    }

    private void readDocActualUri(
            GenerateInputStream stream,
            ContentResolver contentResolver,
            Uri uri
    ) {
        try (InputStream inputStream = stream.generateUri(contentResolver, uri)) {
            readActual(inputStream);
        } catch (IOException e) {
            Log.e(TAG, "io exception: ", e);
        } catch (Exception e) {
            Log.e(TAG, "exception: ", e);
        }
    }

    private void readActual(InputStream inputStream) throws IOException {
        XWPFDocument dcx = new XWPFDocument(inputStream);
        List<XWPFParagraph> paragraphs = dcx.getParagraphs();
        // 获取文件输出流
        int size = paragraphs.size();
        Log.i("Paragraphs count", String.valueOf(size));

        CacheEntity entity = new CacheEntity();

        for (int i = 0; i < size; i++) {
            XWPFParagraph para = paragraphs.get(i);
            int runCount = para.getRuns().size();
            if (runCount == 0) {
                continue;
            }
            Log.i("Operation", "Paragraphs start ==========================");
            String text = para.getText();
            Log.i("Operation", text);
            String number = matchNumber(text);
            if (!TextUtils.isEmpty(number)) {
                entity.setCacheNumber(number);
            }
            String entrusting = matchEntrusting(text);
            if (!TextUtils.isEmpty(entrusting)) {
                entity.setCacheEntrusting(entrusting);
            }
            String identified = matchIdentified(text);
            if (!TextUtils.isEmpty(identified)) {
                entity.setCacheIdentified(identified);
            }
            String sender = matchSender(text);
            if (!TextUtils.isEmpty(sender)) {
                entity.setCacheSender(sender);
            }
            String sendDate = matchSendDate(text);
            if (!TextUtils.isEmpty(sendDate)) {
                entity.setCacheSendDate(sendDate);
            }
            String signDate = matchSignDate(text);
            if (!TextUtils.isEmpty(signDate)) {
                entity.setCacheSignDate(signDate);
            }
            String opinion = matchOpinion(text);
            if (!TextUtils.isEmpty(opinion)) {
                entity.setCacheOpinion(opinion);
            }
            String signature = matchSignature(text);
            if (!TextUtils.isEmpty(signature)) {
                entity.setCacheSignature(signature);
            }
//            for (XWPFRun run : para.getRuns()) {
//                String content = run.getText(0);
//                if (!TextUtils.isEmpty(content)) {
//                    Log.i("Operation", content);
//                }
//            }
            Log.i("Operation", "Paragraphs end --------------------------");
        }
        if (callback != null) {
            callback.onReady(entity);
        }
    }

    /**
     * 匹配档案编号例如 ［2024］年度证泰鉴定（毒物）鉴字第080号
     *
     * @param content content
     */
    private String matchNumber(String content) {
        String text = content.trim();
        String regex = "^［20[0-9]{2}］年度.*鉴字第[0-9]{1,5}号$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(text.trim());
        if (matcher.matches()) {
            Log.e(TAG, text + " is cache number");
            return text;
        }
        return null;
    }

    /**
     * 匹配委托方
     * 例如 委托方：银川市公安局交通管理大队
     *
     * @param content content
     */
    private String matchEntrusting(String content) {
        String text = content.trim();
        String regex = "^委托方：.*$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(text.trim());
        if (matcher.matches()) {
            Log.e(TAG, text.substring(4) + " is cache entrusting");
            return text.substring(4);
        }
        return null;
    }


    /**
     * 委托鉴定事项：对采血管编号为10181844血液检材中乙醇（酒精）含量进行鉴定。
     * cacheIdentified
     */
    private String matchIdentified(String content) {
        String text = content.trim();
        String regex = "^委托鉴定事项：.*$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(text.trim());
        if (matcher.matches()) {
            Log.e(TAG, text.substring(7) + " is cache identified");
            return text.substring(7);
        }
        return null;
    }

    /**
     * 送检人：张少龙、杨学林
     * cacheSender
     */
    private String matchSender(String content) {
        String text = content.trim();
        String regex = "^送检人：.*$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(text.trim());
        if (matcher.matches()) {
            Log.e(TAG, text.substring(4) + " is cache sender");
            return text.substring(4);
        }
        return null;
    }


    /**
     * 委托日期：2024年11月11日
     */
    private String matchSendDate(String content) {
        String text = content.trim();
        String regex = "^委托日期：.*$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(text.trim());
        if (matcher.matches()) {
            Log.e(TAG, text.substring(5) + " is cache sendDate");
            return text.substring(5);
        }
        return null;
    }


    /**
     * 鉴定日期
     */
    private String matchSignDate(String content) {
        String text = content.trim();
        String regex = "^鉴定日期：.*$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(text.trim());
        if (matcher.matches()) {
            Log.e(TAG, text.substring(5) + " is cache signDate");
            return text.substring(5);
        }
        return null;
    }


    /**
     * 鉴定日期
     */
    private String matchOpinion(String content) {
        String text = content.trim();
        String regex = "^.*检出乙醇（酒精）含量.*$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(text.trim());
        if (matcher.matches()) {
            Log.e(TAG, text + " is cache Opinion");
            return text;
        }
        return null;
    }


    /**
     * 鉴定人：詹艳容           鉴定人（授权签字人）：黄文霞
     * Signature
     */
    private String matchSignature(String content) {
        String text = content.trim();
        String regex = "^鉴定人：[\\u4e00-\\u9fa5]+\\x20{0,50}鉴定人（授权签字人）：[\\u4e00-\\u9fa5]+$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(text.trim());
        if (matcher.matches()) {
            Log.e(TAG, text + " is cache Opinion");
            int index = text.indexOf("鉴定人（授权签字人）");
            String first = text.substring(4, index - 1).trim();
            String second = text.substring(index + 11).trim();
            Log.e(TAG, first + "-" + second);
            return first + "、" + second;
        }
        return null;
    }


    public interface Callback {
        void onReady(CacheEntity entity);
    }

}
